package cn.sumpu.app.guoguojie.biz.impl;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import cn.sumpu.app.guoguojie.biz.AlbumBiz;
import cn.sumpu.app.guoguojie.biz.FeedBiz;
import cn.sumpu.app.guoguojie.biz.ImageBiz;
import cn.sumpu.app.guoguojie.constant.FeedIdType;
import cn.sumpu.app.guoguojie.constant.FeedType;
import cn.sumpu.app.guoguojie.constant.PictureType;
import cn.sumpu.app.guoguojie.dao.AlbumDao;
import cn.sumpu.app.guoguojie.dao.PictureDao;
import cn.sumpu.app.guoguojie.domain.Album;
import cn.sumpu.app.guoguojie.domain.Feed;
import cn.sumpu.app.guoguojie.domain.Member;
import cn.sumpu.app.guoguojie.domain.Picture;
import cn.sumpu.app.guoguojie.domain.Ext.PageModel;
import cn.sumpu.app.guoguojie.exception.AppBusinessException;
import cn.sumpu.app.guoguojie.util.Common;
import cn.sumpu.app.guoguojie.util.IdGenerator;
import cn.sumpu.app.guoguojie.util.PictureUrl;

public class AlbumBizImpl implements AlbumBiz {

	private AlbumDao albumDao;

	private PictureDao pictureDao;

	@Autowired
	private FeedBiz feedBiz;

	@Autowired
	private ImageBiz imageBiz;

	private String imageServer;

	public String getImageServer() {
		return imageServer;
	}

	public void setImageServer(String imageServer) {
		this.imageServer = imageServer;
	}

	public void setAlbumDao(AlbumDao albumDao) {
		this.albumDao = albumDao;
	}

	public void setPictureDao(PictureDao pictureDao) {
		this.pictureDao = pictureDao;
	}

	@Override
	public Album createAlbum(Album album) throws AppBusinessException {
		album.setIdentifier(IdGenerator.createIdentifier());
		albumDao.insert(album);
		return album;
	}

	@Override
	public List<Album> viewAlbum() throws AppBusinessException {
		return albumDao.getList(new HashMap<String, Object>());
	}

	@Override
	public PageModel albumList(String family, Integer page)
			throws AppBusinessException {
		Map<String, Object> map = new HashMap<String, Object>();
		Integer startId = (page - 1) * Common.PAGE_SIZE_ALBUM;
		map.put("startId", startId);
		map.put("pageSize", Common.PAGE_SIZE_ALBUM);
		map.put("family", family);
		List<Album> albumList = albumDao.getList(map);
		int count = albumDao.getListCount(map);
		PageModel pm = new PageModel();
		pm.setCurrentPage(page);
		pm.setList(albumList);
		pm.setPageSize(Common.PAGE_SIZE_ALBUM);
		pm.setTotalRecord(count);
		pm.setTotalPage((count + Common.PAGE_SIZE_ALBUM - 1)
				/ Common.PAGE_SIZE_ALBUM);
		return pm;

	}

	@Override
	public PageModel photoList(String family, String album, Integer page)
			throws AppBusinessException {
		Map<String, Object> map = new HashMap<String, Object>();
		Integer startId = (page - 1) * Common.PAGE_SIZE_ALBUM;
		map.put("startId", startId);
		map.put("pageSize", Common.PAGE_SIZE_ALBUM);
		map.put("family", family);
		map.put("album", album);
		List<Picture> picList = pictureDao.getList(map);
		int count = pictureDao.getListCount(map);
		PageModel pm = new PageModel();
		pm.setCurrentPage(page);
		pm.setList(picList);
		pm.setPageSize(Common.PAGE_SIZE_ALBUM);
		pm.setTotalRecord(count);
		pm.setTotalPage((count + Common.PAGE_SIZE_ALBUM - 1)
				/ Common.PAGE_SIZE_ALBUM);
		return pm;

	}

	@Override
	public List<Picture> getPhotoList(String family, String album)
			throws AppBusinessException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("family", family);
		map.put("album", album);
		return pictureDao.getList(map);
	}

	@Override
	public List<Album> getAlbumList(String family) throws AppBusinessException {
		return albumDao.getAlbumList(family);
	}

	@Override
	@Transactional(rollbackForClassName = { "cn.sumpu.app.guoguojie.exception.AppBusinessException" }, timeout = 10)
	public void uploadPhoto(HttpServletRequest request)
			throws AppBusinessException {
		uploadPhoto(request, true);
	}

	public void uploadPhoto(HttpServletRequest request, boolean uploadServer)
			throws AppBusinessException {
		Member member = (Member) request.getSession().getAttribute("member");
		String albumId = request.getParameter("album");

		MultipartHttpServletRequest re = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> map = re.getFileMap();
		List<MultipartFile> fileList = new ArrayList<MultipartFile>();
		for (Object obj : map.values()) {
			MultipartFile file = (MultipartFile) obj;
			fileList.add(file);
		}

		if (fileList.size() > 0) {

			try {
				Feed feed = new Feed();
				int feedImgId = 1;
				for (int i = 0; i < fileList.size(); i++) {
					MultipartFile fj = fileList.get(i);
					String fn = fj.getOriginalFilename();
					if (null != fn && fn.length() > 0) {
						String webAppPath = request.getSession()
								.getServletContext().getRealPath("/");
						String family = member.getFamily();
						String formateDate = Common.getFormatDate(new Date());
						String tmpPath = webAppPath + File.separator + "pic"
								+ File.separator + PictureType.ALBUM.getValue() + File.separator
								+ formateDate + File.separator + family;
						File uploadfujian = new File(tmpPath);
						if (!uploadfujian.exists()) {
							uploadfujian.mkdirs();
						}
						InputStream buffin = new ByteArrayInputStream(fj
								.getBytes());
						BufferedImage bi = ImageIO.read(buffin);
						if (bi != null) {
							String imageType = fn
									.substring(fn.lastIndexOf(".") + 1);
							String uuid = UUID.randomUUID().toString();
							String fujianpath = uploadfujian + File.separator
									+ uuid;
							String savePathServer = "pic/"+PictureType.ALBUM.getValue()+"/" + formateDate
									+ "/" + family;
							int pWidth = bi.getWidth();
							int pHeight = bi.getHeight();
							double zoom = (double) Common.THUMB_WIDTH / pWidth;
							double zoom2 = (double) Common.THUMB_HEIGHT / pHeight;
							if (zoom2 < zoom) {
								zoom = zoom2;
							}
							int tagWidth = (int) (zoom * pWidth);
							int tagHeight = (int) (zoom * pHeight);

							BufferedImage tag = new BufferedImage(tagWidth,
									tagHeight, BufferedImage.TYPE_INT_RGB);
							Graphics g = tag.getGraphics();
							g.drawImage(bi, 0, 0, tagWidth, tagHeight, null);
							g.dispose();
							// 保存缩略图
							String serverUrl = imageServer + "receiveImage.ajax";
							if (!uploadServer) {
								ImageIO.write(tag, imageType, new File(
										fujianpath + "_thumb." + imageType));
							} else {
								ByteArrayOutputStream bao_org = new ByteArrayOutputStream();
								ImageIO.write(tag, imageType, bao_org);
								imageBiz.requestSaveImage(serverUrl, savePathServer,
										uuid + "_thumb." + imageType, bao_org
												.toByteArray());
							}

							// 保存原始图片
							double zoom3 = (double) Common.ORG_WIDTH / pWidth;
							if (zoom3 < 1) {
								int orgWidth = (int) (zoom3 * pWidth);
								int orgHeight = (int) (zoom3 * pHeight);
								BufferedImage tag2 = new BufferedImage(
										orgWidth, orgHeight,
										BufferedImage.TYPE_INT_RGB);
								Graphics g2 = tag2.getGraphics();
								g2.drawImage(bi, 0, 0, orgWidth, orgHeight,
										null);
								g2.dispose();
								if (!uploadServer) {
									ImageIO.write(tag2, imageType, new File(
											fujianpath + "." + imageType));
								} else {
									ByteArrayOutputStream bao = new ByteArrayOutputStream();
									ImageIO.write(tag2, imageType, bao);
									imageBiz.requestSaveImage(serverUrl,
											savePathServer, uuid + "."
													+ imageType, bao
													.toByteArray());
								}
								//	

							} else {
								if (!uploadServer) {
									ImageIO.write(bi, imageType, new File(
											fujianpath + "." + imageType));
								} else {
									ByteArrayOutputStream bao = new ByteArrayOutputStream();
									ImageIO.write(bi, imageType, bao);
									imageBiz.requestSaveImage(serverUrl,
											savePathServer, uuid + "."
													+ imageType, bao
													.toByteArray());
								}
							}

							Picture p = new Picture();
							p.setAlbum(albumId);
							p.setMember(member.getIdentifier());
							String url = savePathServer + "/" + uuid;
							String urlThumb = url + "_thumb." + imageType;
							p.setUrl(url + "." + imageType);
							p.setThumbnail(urlThumb);
							p.setIdentifier(IdGenerator.createIdentifier());
							p.setTitle(fn);
							if (uploadServer)
								p.setImageServer(imageServer);
							pictureDao.insert(p);
							/*
							 * if(i==fileList.size()-1){ cover =
							 * url+"_thumb."+imageType; }
							 */
							switch (feedImgId) {
							case 1: {
								feed.setImg1Path(urlThumb);
								break;
							}
							case 2: {
								feed.setImg2Path(urlThumb);
								break;
							}
							case 3: {
								feed.setImg3Path(urlThumb);
								break;
							}
							case 4: {
								feed.setImg3Path(urlThumb);
								break;
							}
							case 5: {
								feed.setImg3Path(urlThumb);
								break;
							}
							}

							feedImgId++;
						}

					}
				}

				if (!Common.empty(feed.getImg1Path())) {
					feed.setMember(member.getIdentifier());
					feed.setFeedType(FeedType.ALBUM.getValue());
					feed.setFeedId(albumId);
					feed.setFeedIdType(FeedIdType.ALBUMID.getValue());
					feed.setFamily(member.getFamily());
					feedBiz.insert(feed);
				}

			} catch (Exception e) {
				e.printStackTrace();
				throw new AppBusinessException("upload fail", e);
			}

		}

	}
	@Override
	public PictureUrl uploadImage(HttpServletRequest request, boolean uploadServer,String picType,boolean isZip)throws AppBusinessException {
		Member member = (Member) request.getSession().getAttribute("member");
		PictureUrl picUrl = new PictureUrl();
		try {
			MultipartHttpServletRequest re = (MultipartHttpServletRequest) request;
			
			Map<String, MultipartFile> map = re.getFileMap(); 
			List<MultipartFile> fileList = new ArrayList<MultipartFile>();
			for (Object obj : map.values()) {
				MultipartFile file = (MultipartFile) obj;
				fileList.add(file);
			}
			if (fileList.size() > 0) {
				for (int i = 0; i < fileList.size(); i++) {
					MultipartFile fj = fileList.get(i);
					String fn = fj.getOriginalFilename();
					if (null != fn && fn.length() > 0) {
						picUrl.setFileOrgName(fn);
						String webAppPath = request.getSession().getServletContext().getRealPath("/");
						String family = member.getFamily();
						String formateDate = Common.getFormatDate(new Date());
						String tmpPath = webAppPath + File.separator + "pic"+ File.separator + picType + File.separator + formateDate + File.separator + family;
						File uploadfujian = new File(tmpPath);
						if (!uploadfujian.exists()) {
							uploadfujian.mkdirs();
						}
						InputStream buffin = new ByteArrayInputStream(fj.getBytes());
						BufferedImage bi = ImageIO.read(buffin);
						if (bi != null) {
							//文件类型
							String imageType = fn.substring(fn.lastIndexOf(".") + 1);
							String uuid = UUID.randomUUID().toString();
							String fujianpath = uploadfujian + File.separator + uuid;
							String savePathServer = "pic/"+picType+"/" + formateDate + "/" + family;
							int pWidth = bi.getWidth();
							int pHeight = bi.getHeight();
							
							String serverUrl = imageServer + "receiveImage.ajax";
							
							if(isZip){
								double zoom = (double) Common.THUMB_WIDTH / pWidth;
								double zoom2 = (double) Common.THUMB_HEIGHT / pHeight;
								if (zoom2 < zoom) {
									zoom = zoom2;
								}
								int tagWidth = (int) (zoom * pWidth);
								int tagHeight = (int) (zoom * pHeight);

								BufferedImage tag = new BufferedImage(tagWidth,tagHeight, BufferedImage.TYPE_INT_RGB);
								Graphics g = tag.getGraphics();
								g.drawImage(bi, 0, 0, tagWidth, tagHeight, null);
								g.dispose();
								// 保存缩略图
								if (!uploadServer) {
									ImageIO.write(tag, imageType, new File(fujianpath + "_thumb." + imageType));
									
								} else {
									ByteArrayOutputStream bao_org = new ByteArrayOutputStream();
									ImageIO.write(tag, imageType, bao_org);
									imageBiz.requestSaveImage(serverUrl, savePathServer,uuid + "_thumb." + imageType, bao_org.toByteArray());
									
								}
								
								if(picType.equals(PictureType.DOING.getLabel())){
									picUrl.setThumbnail(savePathServer + "/" + uuid + "_thumb." + imageType);
								}else{
									if (!uploadServer) {
										picUrl.setThumbnail(savePathServer + "/" + uuid + "_thumb." + imageType);
									}else{
										picUrl.setThumbnail(imageServer+savePathServer + "/" + uuid + "_thumb." + imageType);
									}
								}
							}
							
							// 保存原始图片
							double zoom3 = (double) Common.ORG_WIDTH / pWidth;
							if(picType.equals(PictureType.DOING.getLabel())){
								zoom3 = (double) Common.ORG_WIDTH_DOING / pWidth;
							}else if(picType.equals(PictureType.DOING.getLabel())){
								zoom3 = (double) Common.ORG_WIDTH_ACTIVITY / pWidth;
							}
							
							if (zoom3 < 1) {
								int orgWidth = (int) (zoom3 * pWidth);
								int orgHeight = (int) (zoom3 * pHeight);
								BufferedImage tag2 = new BufferedImage(orgWidth, orgHeight,BufferedImage.TYPE_INT_RGB);
								Graphics g2 = tag2.getGraphics();
								g2.drawImage(bi, 0, 0, orgWidth, orgHeight,null);
								g2.dispose();
								if (!uploadServer) {
									ImageIO.write(tag2, imageType, new File(fujianpath + "." + imageType));
								} else {
									ByteArrayOutputStream bao = new ByteArrayOutputStream();
									ImageIO.write(tag2, imageType, bao);
									imageBiz.requestSaveImage(serverUrl,savePathServer, uuid + "."+ imageType, bao.toByteArray());
								}

							}else {
								if (!uploadServer) {
									ImageIO.write(bi, imageType, new File(fujianpath + "." + imageType));
								}else {
									ByteArrayOutputStream bao = new ByteArrayOutputStream();
									ImageIO.write(bi, imageType, bao);
									imageBiz.requestSaveImage(serverUrl,savePathServer, uuid + "." + imageType, bao.toByteArray());
								}
							}
							
							
							
							if(picType.equals(PictureType.DOING.getLabel())){
								picUrl.setOriginal(savePathServer + "/" + uuid + "." + imageType);
							}else{
								if (!uploadServer){
									picUrl.setOriginal(savePathServer + "/" + uuid + "." + imageType);
								}else{
									picUrl.setOriginal( imageServer + savePathServer + "/" + uuid + "." + imageType);
								}
							}
							
							if(uploadServer){
								picUrl.setImageServer(imageServer);
							}
							return picUrl;
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new AppBusinessException("upload fail", e);
		}
		return null;
	}

	@Override
	public Album getAlbumById(String id) throws AppBusinessException {
		return albumDao.getById(id);
	}

	@Override
	@Transactional(rollbackForClassName = { "cn.sumpu.app.guoguojie.exception.AppBusinessException" }, timeout = 10)
	public Album saveAlbum(Album album) throws AppBusinessException {
		List<Picture> picList = album.getPictureList();
		String cover = album.getCover();
		for (Picture picture : picList) {
			if ((picture.getThumbnail().equals(cover))) {
				if (!picture.getAlbum().equals(album.getIdentifier())) {
					album.setCover(Common.ALBUM_DEFALUT);
					album.setImageServer("");
				}
			}
			pictureDao.update(picture);
		}

		albumDao.update(album);
		return album;
	}

	@Override
	@Transactional(rollbackForClassName = { "cn.sumpu.app.guoguojie.exception.AppBusinessException" }, timeout = 10)
	public void deleteAlbum(Member member, String webPath, String album)
			throws AppBusinessException {
		albumDao.deleteById(album);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("album", album);
		List<Picture> picList = pictureDao.getList(map);
		for (Picture pic : picList) {
			deletePicFile(pic, webPath);
		}
		pictureDao.deleteByAlbum(album);
		// 删除该专辑产生的动态
		feedBiz.deleteAlbumFeed(member.getIdentifier(), album);
	}

	@Override
	@Transactional(rollbackForClassName = { "cn.sumpu.app.guoguojie.exception.AppBusinessException" }, timeout = 10)
	public void deletePhoto(String webPath, String photoId, String album,
			boolean deleteCoverFlag,String imageServer) throws AppBusinessException {
		Picture pic = pictureDao.getById(photoId);
		deletePicFile(pic, webPath);
		if(Common.empty(imageServer)){
			pictureDao.deleteById(photoId);
		}else{
			imageBiz.deleteImage(pic.getThumbnail());
			imageBiz.deleteImage(pic.getUrl());
		}
		if (deleteCoverFlag) {
			Album albumObj = new Album();
			albumObj.setIdentifier(album);
			albumObj.setCover("");
			albumDao.update(albumObj);
		}

	}

	/**
	 * 删除照片文件
	 * 
	 * @param pic
	 * @param webPath
	 */
	public void deletePicFile(Picture pic, String webPath) {
		String thumb = pic.getThumbnail();
		String url = pic.getUrl();
		File thumbFile = new File(webPath + "/" + thumb);
		File urlFile = new File(webPath + "/" + url);
		if (thumbFile.exists()) {
			thumbFile.delete();
		}
		if (urlFile.exists()) {
			urlFile.delete();
		}
	}

	@Override
	public PageModel albumFriendList(String family, Integer page)
			throws AppBusinessException {
		Map<String, Object> map = new HashMap<String, Object>();
		Integer startId = (page - 1) * Common.PAGE_SIZE_ALBUM;
		map.put("startId", startId);
		map.put("pageSize", Common.PAGE_SIZE_ALBUM);
		map.put("family", family);
		List<Album> albumList = albumDao.getAlbumFriend(map);
		int count = albumDao.getAlbumFriendCount(map);
		PageModel pm = new PageModel();
		pm.setCurrentPage(page);
		pm.setList(albumList);
		pm.setPageSize(Common.PAGE_SIZE_ALBUM);
		pm.setTotalRecord(count);
		pm.setTotalPage((count + Common.PAGE_SIZE_ALBUM - 1)
				/ Common.PAGE_SIZE_ALBUM);
		return pm;
	}

}
